import type { uniappRequestAdapter } from '@alova/adapter-uniapp'
import type { IResponse } from './types'
import AdapterUniapp from '@alova/adapter-uniapp'
import { createAlova } from 'alova'
import { createServerTokenAuthentication } from 'alova/client'
import VueHook from 'alova/vue'
import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth'
import { toast } from '@/utils/toast'
import { ContentTypeEnum, ResultEnum, ShowMessage } from './enum'

const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE
// 配置动态Tag
export const API_DOMAINS = {
  DEFAULT: import.meta.env.VITE_SERVER_BASEURL,
  SECONDARY: import.meta.env.VITE_API_SECONDARY_URL,
}
// 是否正在刷新中
let isRefreshToken = false
// 是否显示重新登录
export const isRelogin = { show: false }
// 请求队列
let requestList: any[] = []
// 请求白名单，无须token的接口
const whiteList: string[] = ['/login', '/refresh-token', '/get-id-by-name']
/**
 * 创建请求实例
 */
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication<
  typeof VueHook,
  typeof uniappRequestAdapter
>({
  refreshTokenOnError: {
    isExpired: (error) => {
      return error.response?.status === ResultEnum.Unauthorized
    },
    handler: async () => {
      try {
        // await authLogin();
      }
      catch (error) {
        // 切换到登录页
        await uni.reLaunch({ url: '/pages/login/login' })
        throw error
      }
    },
  },
})

/**
 * alova 请求实例
 */
const baseURL = import.meta.env.VITE_APP_BASE_URL
const alovaInstance = createAlova({
  baseURL,
  ...AdapterUniapp(),
  cacheFor: null,
  timeout: 5000,
  statesHook: VueHook,
  beforeRequest: onAuthRequired((method) => {
    // 设置默认 Content-Type
    method.config.headers = {
      ContentType: ContentTypeEnum.JSON,
      Accept: 'application/json, text/plain, */*',
      ...method.config.headers,
    }

    const { config, url } = method
    const ignoreAuth = !config.meta?.ignoreAuth
    console.log('ignoreAuth===>', ignoreAuth)

    let isToken = (config!.headers || {}).isToken === false
    whiteList.some((v) => {
      if (url && url.includes(v)) {
        return (isToken = false)
      }
      return false
    })
    if (getAccessToken() && !isToken) {
      config.headers.Authorization = `Bearer ${getAccessToken()}` // 让每个请求携带自定义token
    }

    // 设置租户
    if (tenantEnable && tenantEnable === 'true') {
      const tenantId = getTenantId()
      if (tenantId)
        config.headers['tenant-id'] = tenantId
    }
    // 处理认证信息   自行处理认证问题
    if (ignoreAuth) {
      const token = 'getToken()'
      if (!token) {
        throw new Error('[请求错误]：未登录')
      }
      // method.config.headers.token = token;
    }
    
    // 处理动态域名
    if (config.meta?.domain) {
      method.baseURL = config.meta.domain
      console.log('当前域名', method.baseURL)
    }
  }),
  
  responded: onResponseRefreshToken(async (response, method) => {
    const { config, url } = method
    const { requestType, meta } = config
    const { original } = meta ?? {}
    const {
      statusCode,
      data: rawData,
      errMsg,
    } = response as UniNamespace.RequestSuccessCallbackResult
    // console.log({ response, config, requestType, method, rawData,statusCode }, '🎈')
    // 处理特殊请求类型（上传/下载）
    if (requestType === 'upload' || requestType === 'download') {
      return response
    }

    if (statusCode !== 200) { // 处理 HTTP 状态码错误
      const errorMessage = ShowMessage(statusCode) || `HTTP请求错误[${statusCode}]`
      console.error('errorMessage===>', errorMessage)
      toast.error(errorMessage)
      throw new Error(`${errorMessage}：${errMsg}`)
    }

    const { code, msg, data } = rawData as IResponse
    if (code === 401) {
      if(!getAccessToken()){
        uni.reLaunch({ url: '/pages/login/login' })
        return
      }
      // return
      if (!isRefreshToken) {
        isRefreshToken = true
        // 1. 如果获取不到刷新令牌，则只能执行登出操作
        if (!getRefreshToken()) {
          return handleAuthorized()
        }
        // 2. 进行刷新访问令牌
        try {
          const refreshTokenRes = await refreshToken()
          // 2.1 刷新成功，则回放队列的请求 + 当前请求
          setToken((await refreshTokenRes).data.data)
          config.headers!.Authorization = `Bearer ${getAccessToken()}`
          requestList.forEach((cb: any) => {
            cb()
          })
          requestList = []
          // return service(config)
          return alovaInstance.Request(method)
        }
        catch (e) {
          // 为什么需要 catch 异常呢？刷新失败时，请求因为 Promise.reject 触发异常。
          // 2.2 刷新失败，只回放队列的请求
          requestList.forEach((cb: any) => {
            cb()
          })
          // 提示是否要登出。即不回放当前请求！不然会形成递归
          return handleAuthorized()
        } 
        finally {
          requestList = []
          isRefreshToken = false
        }
      } else {
        // 添加到队列，等待刷新获取到新的令牌
        return new Promise((resolve) => {
          requestList.push(() => {
            config.headers!.Authorization = `Bearer ${getAccessToken()}` // 让每个请求携带自定义token 请根据实际情况自行修改
            resolve(alovaInstance.Request(method))
          })
        })
      }
    }
    else if (code !== ResultEnum.Success) {// 处理业务逻辑错误
      if (config.meta?.toast !== false) {
        toast.warning(msg)
      }
      throw new Error(`请求错误[${code}]：${msg}`)
    }
    if (original) { // 基于需求返回原始数据
      return rawData
    }
    // 处理成功响应，返回业务数据
    return data
  }),
})

async function refreshToken() {
  // alova.defaults.headers.common['tenant-id'] = getTenantId()
  // return await alova.Post(`${baseURL}/system/auth/refresh-token?refreshToken=${getRefreshToken()}`)
  return fetch(`${baseURL}/system/auth/refresh-token?refreshToken=${getRefreshToken()}`, {
    method: 'POST', // 或 'POST', 'PUT' 等
    headers: {
      'Content-Type': 'application/json',
      'tenant-id': getTenantId(), // 设置tenant-id头部
      // 可以添加其他需要的头部
    },
  })
}
function handleAuthorized() {
  if (!isRelogin.show) {
    isRelogin.show = true
    uni.showModal({
      title: '提示',
      content: '登录超时,请重新登录!',
      cancelText: '取消',
      confirmText: '确定',
      success(res) { 
        const {confirm,cancel} = res
        if(confirm){
          // resetRouter() // 重置静态路由表
          // deleteUserCache() // 删除用户缓存
          removeToken()
          uni.reLaunch({ url: '/pages/login/login' })
        }
        isRelogin.show = false
        isRefreshToken = false
      }
    })
  }
  return Promise.reject('登录超时，请重新登录')
}
// export const http = alovaInstance
export const request = alovaInstance
